package com.ming_za.odupdaterserver.core.thread;

import com.ming_za.odupdaterserver.OdUpdaterServerApplication;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 阻塞型线程池，当队列满时将阻塞{@link #execute(Runnable)}
 */
public class BlockExecuteTreadPool {

    private final ThreadPoolExecutor threadPoolExecutor;
    private final BlockingQueue<Runnable> blockingQueue;

    public BlockExecuteTreadPool(int coreSize,int queueSize) {
        this.blockingQueue = new LinkedBlockingQueue<>(queueSize);
        this.threadPoolExecutor = new ThreadPoolExecutor(coreSize,coreSize,1, TimeUnit.MINUTES,blockingQueue);
        OdUpdaterServerApplication.registerStopFunc(unused -> {
//            System.out.println("尝试关闭"+threadPoolExecutor+"线程");
            shutdown();
//            System.out.println(threadPoolExecutor+"线程已关闭");
        });
    }

    public void execute(Runnable runnable) throws InterruptedException {
        if (threadPoolExecutor.getActiveCount() == 0) {
            threadPoolExecutor.execute(runnable);
        }else {
            blockingQueue.put(()->{
                runnable.run();
                synchronized (blockingQueue) {
                    blockingQueue.notify();
                }
            });
        }
    }

    public void shutdown() {
        threadPoolExecutor.shutdown();
        try {
            threadPoolExecutor.awaitTermination(Long.MAX_VALUE,TimeUnit.DAYS);
        } catch (InterruptedException ignored) {

        }
    }

    public void awaitTerminationAndShutdown(long timeout, TimeUnit unit) throws InterruptedException {
        if (!blockingQueue.isEmpty()) {
            synchronized (blockingQueue) {
                while (!blockingQueue.isEmpty()) {
                    blockingQueue.wait();
                }
            }
        }
        shutdown();
        threadPoolExecutor.awaitTermination(timeout,unit);
    }
}
